/**
 *  Copyright 24.08.2012 oliver.keusemann@googlemail.com
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package de.xelerity.geolessi.srv.impl.mixed;

import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

@SuppressWarnings("unchecked")
public class CacheServiceSR<T> {

	private static Map<String, HashMap<Integer, SoftReference<?>>> allmaps = new HashMap<String, HashMap<Integer, SoftReference<?>>>();

	private static HashMap<Integer, SoftReference<?>> getMap(Class<?> C) {
		HashMap<Integer, SoftReference<?>> object = allmaps.get(C.getName());
		if (object == null) {
			object = new HashMap<Integer, SoftReference<?>>();
			allmaps.put(C.getName(), object);
		}
		return object;
	}

	private HashMap<Integer, SoftReference<?>> map;

	public CacheServiceSR(Class<?> C) {
		map = getMap(C);
	}

	public T get(int key) {
		SoftReference<T> softRef = (SoftReference<T>) map.get(key);
		if (softRef != null && softRef.get() == null) {
			map.remove(key);
			clean();
			return null;
		}
		return softRef == null ? null : softRef.get();
	}

	private void clean() {
		Vector<Integer> removeList = new Vector<Integer>();
		int cnt = 0;
		for (Map.Entry<Integer, SoftReference<?>> E : map.entrySet()) {
			if (E.getValue() == null || E.getValue().get() == null) {
				removeList.add(E.getKey());
			}
			cnt++;
			if (cnt > 250)
				;// break;
		}

		for (Integer R : removeList) {
			System.out.println(R);
			map.remove(R);
		}

	}

	public void put(int key, T value) {
		if (value != null) {
			map.put(key, new SoftReference<T>(value));
		}
		return;
	}

	public T remove(int key) {
		SoftReference<T> softRef = (SoftReference<T>) map.remove(key);
		if (softRef == null)
			return null;
		T oldValue = softRef.get();
		softRef.clear();
		return oldValue;
	}

	public static void main(String[] args) {

		CacheServiceSR<String> cachServiceWR = new CacheServiceSR<String>(String.class);

		cachServiceWR.put(1, "D");
		System.out.println(cachServiceWR.get(1));

		for (int i = 0; i < Integer.MAX_VALUE; i++) {
			try {
				Thread.sleep(90);
			} catch (InterruptedException e) {
				;
			}
			cachServiceWR.put(i, i + "--" + (i * 2) + "fiewfjiew fjewi fjiew ofjiwe fjeiw fjeiwo fjeio fjewi" + i);
			// System.out.println(" " + cachServiceWR.get(i));
			if (null == cachServiceWR.get(i)) {
				System.out
						.println("----------------------------------------------------------------------------------------------------------");
			}

			int neg = 0, pos = 0;
			if (i > 1000) {
				for (int j = 0; j < i; j++) {
					Object a = cachServiceWR.get(j);
					if (a == null)
						neg++;
					else
						pos++;
				}
				System.out.println(pos + " gefunden. " + neg + " nicht gefunden");
			}

		}
	}
}
